package xgorm

import (
	"fmt"
	"sync"
	"time"
	
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
	"github.com/spf13/viper"
	"gitlab-tech.shruisong.cn/growth/go-common/pkg/utils"
)

const errDBConfigKeyNil = "db config nil: %s"

func NewMysqlDB(name string) (db *gorm.DB, err error) {
	db = ds.get(name)
	if db != nil && db.DB().Ping() == nil{
		return
	}
	key := "db." + name
	if !viper.IsSet(key) {
		err = fmt.Errorf(errDBConfigKeyNil, key)
		return
	}
	
	if db, err = gorm.Open("mysql", viper.GetString(key+".dsn")); err != nil {
		return
	}
	
	db.DB().SetMaxOpenConns(viper.GetInt(key + ".active"))
	db.DB().SetMaxIdleConns(viper.GetInt(key + ".idle"))
	db.DB().SetConnMaxLifetime(time.Second * 600)
	if !utils.IsProduction(){
		db.LogMode(true)
	}
	
	if err = db.DB().Ping(); err != nil{
		return
	}
	
	ds.add(name, db)
	return
}


type dbs struct {
	dbs map[string] *gorm.DB
	sync.RWMutex
}

var ds *dbs

func init()  {
	ds = &dbs{
		dbs: make(map[string]*gorm.DB),
	}
}

func (d *dbs) add(name string, conn *gorm.DB) {
	d.Lock()
	defer d.Unlock()
	d.dbs[name] = conn
}

func (d *dbs)get(name string) *gorm.DB {
	d.RLock()
	defer d.RUnlock()
	return d.dbs[name]
}

